package com.boat.starter.mockit.service;

import com.boat.starter.mockit.props.MockitProperties;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 规则匹配服务
 * 
 * @author 周江
 *
 */
@Slf4j
public class MockitMatchService {
	private MockitProperties mockitProperties;

	public MockitMatchService(MockitProperties mockitProperties) {
		this.mockitProperties = mockitProperties;
	}

	/**
	 * 路径是否允许mock
	 * 
	 * 匹配格式，支持： 1，精确匹配：/supportClient/accountInfo 2，全量匹配：/supportClient/*
	 * 3，前缀匹配：/supportClient/query* 4，多方法匹配：/supportClient/(query*|accountInfo2)
	 * 
	 * @param mockMappingValue
	 * @return
	 */
	public boolean isMocked(String mapping) {
		if (StrUtil.isBlank(mapping)) {
			return false;
		}
		
		if (!mockitProperties.getEnabled()) {
			// 未开启mock
			return false;
		}

		String pattern = matchePattern(mapping, mockitProperties.getExcludes());
		if (StrUtil.isNotBlank(pattern)) {
			log.info("此方法已匹配Excludes规则,不会调用Mock服务。MockMapping:{}, 规则:{}", mapping, pattern);
			return false;
		}

		pattern = matchePattern(mapping, mockitProperties.getMethods());
		if (StrUtil.isNotBlank(pattern)) {
			log.info("此方法已匹配Methods规则,将调用Mock服务。MockMapping:{}, 规则:{}", mapping, pattern);
			return true;
		}

		// 默认不mock
		// log.info("此方法未匹配任何规则,走真实接口。方法名:{}",mapping);
		return false;
	}

	private String matchePattern(String mapping, String patterns) {
		if (StrUtil.isBlank(mapping) || StrUtil.isBlank(patterns)) {
			return null;
		}

		String[] patternArray = patterns.split(",");
		for (String pattern : patternArray) {
			if (StrUtil.isNotBlank(pattern)) {
				// *号转为正则表达式\w*
				String regExpr = pattern.replaceAll("\\*", "\\\\\\w*");
				if (mapping.matches(regExpr)) {
					return pattern;
				}
			}
		}

		return null;
	}

}
